/*
* ============================================================================
*  Name     : VersionChecker.cpp
*  Part of  : GV60
*  Copyright: Wipo Software
* ============================================================================
*/

#include "VersionChecker.h"
#include "HttpModule.h"
#include "Logger.h"

#define HTTP_TIMEOUT   30000

_LIT8(KVersionUrl,     "http://www.mrunner.net/version.txt");


VersionChecker::VersionChecker(MVersionCheckerObserver* n_pObserver)
{
  m_bBusy       = EFalse;
  m_pHttpModule = NULL;
  m_pObserver   = n_pObserver;

  m_iVersion.iMajor = 0;
  m_iVersion.iMinor = 0;
  m_iVersion.iBuild = 0;
}

VersionChecker::~VersionChecker()
{
  if (m_pHttpModule)
  {
    delete m_pHttpModule;
    m_pHttpModule = NULL;
  }
}

void VersionChecker::CancelRequest()
{
  DEBUG1("VersionChecker::CancelRequest");

  if (!m_bBusy)
  {
    return;
  }

  if (m_pHttpModule != NULL)
  {
    if (m_pHttpModule->IsRunning())
    {
      m_pHttpModule->CancelTransaction();
    }
  }
  
  m_bBusy = EFalse;
}

TInt VersionChecker::DownloadVersion()
{
  DEBUG1("VersionChecker::DownloadVersion");
  
  if (m_bBusy)
  {
    return KErrInUse;
  }

  // Delete old instance of HTTP module
  if (m_pHttpModule)
  {
    delete m_pHttpModule;
    m_pHttpModule = NULL;
  }

  // Create new instance of HTTP module
  m_pHttpModule = CHttpModule::NewL(this);
  
  TInt iHttpResult = m_pHttpModule->IssueHTTPGetL(KVersionUrl, HTTP_TIMEOUT);
  if (iHttpResult == KErrNone)
  {
    m_bBusy = ETrue;
  }
  
  return iHttpResult;
}

void VersionChecker::HttpResult(TInt iStatusCode, const TDesC8& n_iResponseBody)
{
  DEBUG2("VersionChecker::HttpResult - status code = ", iStatusCode);
  DEBUG2("VersionChecker::HttpResult - len = ", n_iResponseBody.Size());
  DEBUG2("VersionChecker::HttpResult - dump:", n_iResponseBody);

  if (!m_bBusy)
  {
    // This should never happen!
    return;
  }
  
  m_bBusy = EFalse;
  HttpResultVersion(iStatusCode, n_iResponseBody);
}

void VersionChecker::HttpResultVersion(TInt iStatusCode, const TDesC8& n_iResponseBody)
{
  TInt iResult = KErrNone;  
  if (iStatusCode >= 200 && iStatusCode < 300)
  {
    iResult = ParseVersionString(n_iResponseBody, m_iVersion);
  }
  else
  {
    iResult = (iStatusCode == 408) ? KErrTimedOut : KErrUnknown;
  }

  if (m_pObserver)
  {
    m_pObserver->VersionReady(iResult, m_iVersion);
  }
}

TInt VersionChecker::VersionToString(const TGV60Version& n_iVersion, TDes& n_iString)
{
  n_iString.Zero();
  
  n_iString.Num(n_iVersion.iMajor);
  n_iString.Append('.');
  n_iString.AppendNum(n_iVersion.iMinor);
  n_iString.Append('.');
  n_iString.AppendNum(n_iVersion.iBuild);
  
  return KErrNone;
}

TInt VersionChecker::ParseVersionString(const TDesC8& n_iString, TGV60Version& n_iVersion)
{
  TInt iLen   = n_iString.Length();
  TInt iToken = 0;
  
  n_iVersion.iMajor = 0;
  n_iVersion.iMinor = 0;
  n_iVersion.iBuild = 0;
  
  for (TInt i = 0; i < iLen; i++)
  {
    if (n_iString[i] >= '0' && n_iString[i] <= '9')
    {
      TInt iValue = n_iString[i] - '0';
      switch(iToken)
      {
        case 0:
          n_iVersion.iMajor = (n_iVersion.iMajor * 10) + iValue;
          break;
        case 1:
          n_iVersion.iMinor = (n_iVersion.iMinor * 10) + iValue;
          break;
        case 2:
          n_iVersion.iBuild = (n_iVersion.iBuild * 10) + iValue;
          break;
        default:
          return KErrUnknown;
      }
    }
    else if (n_iString[i] == '.')
    {
      iToken++;
      if (iToken > 2)
      {
        return KErrUnknown;
      }
    }
    else if (n_iString[i] == ' ')
    {
      // Nothing to do... ignore these characters
    }
    else
    {
      return KErrUnknown;
    }
  }

  return KErrNone;
}

